import { Component, Node, _decorator } from 'cc';
import { MessageDispatcher } from './MessageDispatcher';
import { MessageQueue } from './MessageQueue';
import { MessageType, IMessage, MessagePriority } from './MessageTypes';
import { LOG } from '../../../ConsoleLogCtrl';

const { ccclass, property } = _decorator;

/**
 * 消息管理器
 * 负责统一管理游戏中的消息系统，包括消息分发、队列管理等
 */
@ccclass('MessageManager')
export class MessageManager extends Component {
    /** 消息分发器 */
    private messageDispatcher: MessageDispatcher;
    
    /** 消息队列 */
    private messageQueue: MessageQueue;
    
    /** 单例实例 */
    private static _instance: MessageManager;
    
    /** 是否已初始化 */
    private _initialized: boolean = false;
    
    /** 消息处理间隔（毫秒） */
    @property({
        displayName: '消息处理间隔(ms)',
        tooltip: '每次处理消息队列的时间间隔'
    })
    public messageProcessInterval: number = 16; // 约60fps
    
    /** 每帧最大处理消息数量 */
    @property({
        displayName: '每帧最大处理消息数',
        tooltip: '每帧最多处理的消息数量，避免卡顿'
    })
    public maxMessagesPerFrame: number = 10;
    
    /**
     * 获取单例实例
     */
    public static getInstance(): MessageManager {
        return MessageManager._instance;
    }
    
    /**
     * 组件初始化
     */
    protected onLoad(): void {
        LOG.warn('MessageManager onLoad: 初始化消息管理器');
        if (MessageManager._instance && MessageManager._instance !== this) {
            LOG.warn('MessageManager已存在实例，销毁当前实例');
            return;
        }
        
        MessageManager._instance = this;
        this.initialize();
    }
    
    /**
     * 初始化消息管理器
     */
    private initialize(): void {
        if (this._initialized) {
            return;
        }
        
        // 初始化消息分发器
        this.messageDispatcher = new MessageDispatcher();
        
        // 初始化消息队列
        this.messageQueue = new MessageQueue();
        
        // 启动消息处理循环
        this.startMessageProcessing();
        
        this._initialized = true;
        LOG.log('MessageManager初始化完成');
    }
    
    /**
     * 启动消息处理循环
     */
    private startMessageProcessing(): void {
        this.schedule(this.processMessages, this.messageProcessInterval / 1000);
    }
    
    /**
     * 处理消息队列
     */
    private processMessages(): void {
        let processedCount = 0;
        
        while (processedCount < this.maxMessagesPerFrame && !this.messageQueue.isEmpty()) {
            const message = this.messageQueue.dequeue();
            if (message) {
                this.messageDispatcher.dispatch(message);
                processedCount++;
            }
        }
    }
    
    /**
     * 发送消息
     * @param type 消息类型
     * @param data 消息数据
     * @param priority 消息优先级
     * @param immediate 是否立即处理
     */
    public sendMessage<T = any>(
        type: MessageType, 
        data?: T, 
        priority: MessagePriority = MessagePriority.NORMAL,
        immediate: boolean = false
    ): void {
        const message: IMessage<T> = {
            id: this.generateMessageId(),
            type,
            data,
            priority,
            timestamp: Date.now(),
            sender: 'MessageManager'
        };
        
        if (immediate) {
            // 立即处理消息
            this.messageDispatcher.dispatch(message);
        } else {
            // 加入队列等待处理
            this.messageQueue.enqueue(message);
        }
    }
    
    /**
     * 订阅消息
     * @param type 消息类型
     * @param callback 回调函数
     * @param target 目标对象
     */
    public subscribe<T = any>(
        type: MessageType, 
        callback: (message: IMessage<T>) => void, 
        target?: any
    ): void {
        this.messageDispatcher.subscribe(type, callback, target);
    }
    
    /**
     * 取消订阅消息
     * @param type 消息类型
     * @param callback 回调函数
     * @param target 目标对象
     */
    public unsubscribe<T = any>(
        type: MessageType, 
        callback?: (message: IMessage<T>) => void, 
        target?: any
    ): void {
        this.messageDispatcher.unsubscribe(type, callback, target);
    }
    
    /**
     * 取消目标对象的所有订阅
     * @param target 目标对象
     */
    public unsubscribeTarget(target: any): void {
        this.messageDispatcher.unsubscribeTarget(target);
    } 
    
    /**
     * 广播消息（立即发送给所有订阅者）
     * @param type 消息类型
     * @param data 消息数据
     */
    public broadcast<T = any>(type: MessageType, data?: T): void {
        this.sendMessage(type, data, MessagePriority.HIGH, true);
    }
    
    /**
     * 延迟发送消息
     * @param type 消息类型
     * @param data 消息数据
     * @param delay 延迟时间（秒）
     * @param priority 消息优先级
     */
    public sendDelayedMessage<T = any>(
        type: MessageType, 
        data?: T, 
        delay: number = 0,
        priority: MessagePriority = MessagePriority.NORMAL
    ): void {
        this.scheduleOnce(() => {
            this.sendMessage(type, data, priority);
        }, delay);
    }
    
    /**
     * 清空消息队列
     */
    public clearMessageQueue(): void {
        this.messageQueue.clear();
    }
    
    /**
     * 获取消息队列长度
     */
    public getQueueLength(): number {
        return this.messageQueue.size();
    }
    
    /**
     * 获取订阅者数量
     * @param type 消息类型
     */
    public getSubscriberCount(type: MessageType): number {
        return this.messageDispatcher.getSubscriberCount(type);
    }
    
    /**
     * 生成消息ID
     */
    private generateMessageId(): string {
        return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    }
    
    /**
     * 获取消息统计信息
     */
    public getStatistics(): {
        queueLength: number;
        totalSubscribers: number;
        processInterval: number;
        maxPerFrame: number;
    } {
        return {
            queueLength: this.getQueueLength(),
            totalSubscribers: this.messageDispatcher.getTotalSubscriberCount(),
            processInterval: this.messageProcessInterval,
            maxPerFrame: this.maxMessagesPerFrame
        };
    }
    
    /**
     * 设置消息处理参数
     * @param interval 处理间隔（毫秒）
     * @param maxPerFrame 每帧最大处理数量
     */
    public setProcessingParams(interval: number, maxPerFrame: number): void {
        this.messageProcessInterval = Math.max(1, interval);
        this.maxMessagesPerFrame = Math.max(1, maxPerFrame);
        
        // 重新启动消息处理
        this.unschedule(this.processMessages);
        this.startMessageProcessing();
    }
    
    /**
     * 组件销毁
     */
    protected onDestroy(): void {
        if (MessageManager._instance === this) {
            // 清理资源
            this.unschedule(this.processMessages);
            this.clearMessageQueue();
            
            if (this.messageDispatcher) {
                this.messageDispatcher.clear();
            }
            
            MessageManager._instance = null;
            LOG.log('MessageManager已销毁');
        }
    }
}